home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Utilities / MView / wndproc.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-09-30  |  68.7 KB  |  1,767 lines

  1. /*//////////////////////////////////////////////////////////////////////////////
  2. //
  3. // File: wndproc.cpp
  4. //
  5. // Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
  6. //
  7. //
  8. //////////////////////////////////////////////////////////////////////////////*/
  9.  
  10. #include "mviewpch.h"
  11.  
  12. #ifndef WM_MOUSEWHEEL
  13. #define WM_MOUSEWHEEL                   0x020A
  14. #endif
  15.  
  16. // callbacks defined in DlgProc.cpp
  17. LRESULT CALLBACK DlgProcAbout(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
  18. LRESULT CALLBACK DlgProcSimplify(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
  19. LRESULT CALLBACK DlgProcSimplifyFaces(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
  20. LRESULT CALLBACK DlgProcProperties(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
  21. LRESULT CALLBACK DlgProcFaceInfo(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
  22. LRESULT CALLBACK DlgProcVertexInfo(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
  23. LRESULT CALLBACK DlgProcMeshInfo(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
  24. LRESULT CALLBACK DlgProcOutput(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
  25.  
  26. HRESULT GenerateMesh(SMeshContainer *pmcMesh);
  27.  
  28. LRESULT
  29. TrivialData::WndProcCallback(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
  30. {
  31.     return g_pData->OnMessage(g_pData->m_hwnd, msg, wparam, lparam);
  32. }
  33.  
  34. LRESULT
  35. TrivialData::OnMessage(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
  36. {
  37.     HRESULT hr;
  38.     const float x_fSlackDelta = 0.05f;
  39.  
  40.     RECT r;
  41.     switch (msg)
  42.     {
  43.         case WM_CREATE:
  44.             // UNDONE UNDONE , it would be really nice to get this message
  45.         return 0;
  46.  
  47.         case WM_DESTROY:
  48.             KillTimer(hwnd, 1);
  49.             return 0;
  50.  
  51.         case WM_SETCURSOR:
  52. #if 0
  53.             if (
  54.                  bFullScreen //&&
  55.                  //bActive &&
  56.                  //! bPaused
  57.                  )
  58.             {
  59.                 SetCursor( NULL );
  60.                 return 1;
  61.             }
  62. #endif
  63.             break;
  64.  
  65.         case WM_TIMER:
  66.             break;
  67.  
  68.         case WM_KEYDOWN:
  69.             if ( VK_ESCAPE == (int) wparam )
  70.                 return 1;
  71. #if 0
  72.             else if ( 'k' == wparam || 'K' == wparam )
  73.             {
  74.                 FixNPatchCreases();
  75.             }
  76. #endif
  77.             else if ('1' == wparam)
  78.             {
  79. #if 0
  80.                 if (m_pmcSelectedMesh != NULL && m_pmcSelectedMesh->pMesh != NULL)
  81.                 {
  82.                     D3DXATTRIBUTERANGE rgAttribTable[10];
  83.                     DWORD caeAttribTable;
  84.  
  85.                     m_pmcSelectedMesh->pMesh->GetAttributeTable(rgAttribTable, &caeAttribTable);
  86.  
  87.                     m_pmcSelectedMesh->pMesh->SetAttributeTable(rgAttribTable, caeAttribTable);
  88.                 }
  89.  
  90.                 D3DVERTEXELEMENT9 pDecl1[18];
  91.                 D3DVERTEXELEMENT9 pDecl2[18];
  92.                 D3DVERTEXELEMENT9 *pCur;
  93.                 LPD3DXMESH pMeshTemp;
  94.  
  95.                 if (m_pmcSelectedMesh != NULL && m_pmcSelectedMesh->pMesh != NULL)
  96.                 {
  97.                     m_pmcSelectedMesh->pMesh->GetDeclaration(pDecl1);
  98.                     m_pmcSelectedMesh->pMesh->GetDeclaration(pDecl2);
  99.  
  100.                     pCur = pDecl2;
  101.                     while (pCur->Stream != 0xff)
  102.                     {
  103.                         if (pCur->Usage == D3DDECLUSAGE_NORMAL)
  104.                         {
  105.                             pCur->Type = D3DDECLTYPE_SHORT4N;
  106.                         }
  107.                     pCur++;                   
  108.                     }
  109.  
  110.                     // convert normals to different format
  111.                     m_pmcSelectedMesh->pMesh->CloneMesh(
  112.                                         m_pmcSelectedMesh->pMesh->GetOptions(), 
  113.                                         pDecl2,
  114.                                         m_pDevice, &pMeshTemp);
  115.  
  116.                     // now convert them back to Float3
  117.                     GXRELEASE(m_pmcSelectedMesh->pMesh);
  118.                     pMeshTemp->CloneMesh(
  119.                                         pMeshTemp->GetOptions(), 
  120.                                         pDecl1,
  121.                                         m_pDevice, &m_pmcSelectedMesh->pMesh);
  122.  
  123.                     GXRELEASE(m_pmcSelectedMesh->ptmDrawMesh);
  124.                     m_pmcSelectedMesh->ptmDrawMesh = m_pmcSelectedMesh->pMesh;
  125.                     m_pmcSelectedMesh->ptmDrawMesh->AddRef();
  126.                 }
  127. #endif
  128.                 if ((m_pdeSelected != NULL) && (m_pdeSelected->m_pAnimMixer != NULL))
  129.                 {
  130.                     m_pdeSelected->m_pAnimMixer->KeyTrackSpeed(0, 2.0f, m_pdeSelected->m_pAnimMixer->GetTime(), 1.0f, D3DXTRANSITION_LINEAR);
  131.                     m_pdeSelected->m_pAnimMixer->KeyTrackSpeed(1, 2.0f, m_pdeSelected->m_pAnimMixer->GetTime(), 1.0f, D3DXTRANSITION_LINEAR);
  132.                 }
  133.             }
  134.             else if ('2' == wparam)
  135.             {
  136.                 if ((m_pdeSelected != NULL) && (m_pdeSelected->m_pAnimMixer != NULL))
  137.                 {
  138.                     m_pdeSelected->m_pAnimMixer->KeyTrackSpeed(0, 1.0f, m_pdeSelected->m_pAnimMixer->GetTime(), 1.0f, D3DXTRANSITION_LINEAR);
  139.                     m_pdeSelected->m_pAnimMixer->KeyTrackSpeed(1, 1.0f, m_pdeSelected->m_pAnimMixer->GetTime(), 1.0f, D3DXTRANSITION_LINEAR);
  140.                 }
  141.             }
  142.             else if ('3' == wparam)
  143.             {
  144.                 if ((m_pdeSelected != NULL) && (m_pdeSelected->m_pAnimMixer != NULL))
  145.                 {
  146.                     m_pdeSelected->m_pAnimMixer->KeyTrackSpeed(0, 0.0f, m_pdeSelected->m_pAnimMixer->GetTime(), 1.0f, D3DXTRANSITION_LINEAR);
  147.                     m_pdeSelected->m_pAnimMixer->KeyTrackSpeed(1, 0.0f, m_pdeSelected->m_pAnimMixer->GetTime(), 1.0f, D3DXTRANSITION_LINEAR);
  148.                 }
  149.             }
  150.             else if ('4' == wparam)
  151.             {
  152.                 m_pdeSelected->m_pAnimMixer->KeyTrackWeight(0, 0.0f, m_pdeSelected->m_pAnimMixer->GetTime(), 0.2f, D3DXTRANSITION_LINEAR);
  153.                 m_pdeSelected->m_pAnimMixer->KeyTrackWeight(1, 1.0f, m_pdeSelected->m_pAnimMixer->GetTime(), 0.2f, D3DXTRANSITION_LINEAR);
  154.             }
  155.             else if ('5' == wparam)
  156.             {
  157.                 m_pdeSelected->m_pAnimMixer->KeyTrackWeight(0, 1.0f, m_pdeSelected->m_pAnimMixer->GetTime(), 0.2f, D3DXTRANSITION_LINEAR);
  158.                 m_pdeSelected->m_pAnimMixer->KeyTrackWeight(1, 0.0f, m_pdeSelected->m_pAnimMixer->GetTime(), 0.2f, D3DXTRANSITION_LINEAR);
  159.             }
  160.             else if ('6' == wparam)
  161.             {
  162.                 m_pdeSelected->m_pAnimMixer->SetTrackEnable(1, TRUE);
  163.                 m_pdeSelected->m_pAnimMixer->SetTrackSpeed(1, 0.0f);
  164.             }
  165.             else if ('7' == wparam)
  166.             {
  167.                 m_pdeSelected->m_pAnimMixer->SetTrackWeight(0, 1.0f);
  168.                 m_pdeSelected->m_pAnimMixer->SetTrackWeight(1, 0.0001f);
  169.             }
  170.             else if ('8' == wparam)
  171.             {
  172.                 m_pdeSelected->m_pAnimMixer->SetTrackWeight(0, 1.0f);
  173.                 m_pdeSelected->m_pAnimMixer->SetTrackWeight(1, 0.0f);
  174.             }
  175.             else if ('9' == wparam)
  176.             {
  177.                 m_pdeSelected->m_pAnimMixer->SetTrackPosition(0, 0.0f);
  178.             }
  179.             else if ('0' == wparam)
  180.             {
  181.                 //m_pdeSelected->m_pAnimMixer->SetTrackAnimTime(0, (FLOAT)m_pdeSelected->m_rgpAnimSets[0]->m_pAnimSet->GetPeriod()-0.00001f);
  182.             }
  183.             else if (('h' == wparam) || ('H' == wparam))
  184.             {
  185.                 D3DVERTEXELEMENT9 pDeclaration[20];
  186.                 DWORD dwFVF;
  187.                 DWORD dwFVFOrig = D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1;
  188.  
  189.                 D3DXDeclaratorFromFVF(dwFVFOrig, pDeclaration);
  190.                 D3DXFVFFromDeclarator(pDeclaration, &dwFVF);
  191.                 GXASSERT(dwFVF == dwFVFOrig);
  192.             }
  193.  
  194.  
  195. #if 0
  196.             else if ( 'h' == wparam || 'H' == wparam )
  197.             {
  198.                 DWORD cIndices;
  199.                 LPD3DXBUFFER pbufTemp;
  200.  
  201.                 if ((m_pmcSelectedMesh != NULL) && (m_pmcSelectedMesh->pMesh != NULL))
  202.                 {
  203.                     if (0)
  204.                     {
  205.                         m_pmcSelectedMesh->m_rgcStripIndices = new DWORD[m_pmcSelectedMesh->m_cAttributeGroups];
  206.                         m_pmcSelectedMesh->m_rgpStrips = new LPDIRECT3DINDEXBUFFER9[m_pmcSelectedMesh->m_cAttributeGroups];
  207.                         DWORD iAttrib;
  208.                         for (iAttrib = 0; iAttrib < m_pmcSelectedMesh->m_cAttributeGroups; iAttrib++)
  209.                         {
  210.                             hr = D3DXConvertMeshSubsetToSingleStrip(m_pmcSelectedMesh->pMesh, iAttrib, D3DXMESH_IB_MANAGED, &(m_pmcSelectedMesh->m_rgpStrips[iAttrib]), &(m_pmcSelectedMesh->m_rgcStripIndices[iAttrib]));
  211.                             GXASSERT(!FAILED(hr));
  212.                         }
  213.                     }
  214.                     else
  215.                     {
  216.                         m_pmcSelectedMesh->m_rgrgcStripCounts = new DWORD*[m_pmcSelectedMesh->m_cAttributeGroups];
  217.                         m_pmcSelectedMesh->m_rgcStrips = new DWORD[m_pmcSelectedMesh->m_cAttributeGroups];
  218.                         m_pmcSelectedMesh->m_rgpStrips = new LPDIRECT3DINDEXBUFFER9[m_pmcSelectedMesh->m_cAttributeGroups];
  219.                         DWORD iAttrib;
  220.                         for (iAttrib = 0; iAttrib < m_pmcSelectedMesh->m_cAttributeGroups; iAttrib++)
  221.                         {
  222.                             hr = D3DXConvertMeshSubsetToStrips(m_pmcSelectedMesh->pMesh, iAttrib, D3DXMESH_IB_MANAGED, &(m_pmcSelectedMesh->m_rgpStrips[iAttrib]), NULL, &pbufTemp, &(m_pmcSelectedMesh->m_rgcStrips[iAttrib]));
  223.                             GXASSERT(!FAILED(hr));
  224.  
  225.                             m_pmcSelectedMesh->m_rgrgcStripCounts[iAttrib] = new DWORD[m_pmcSelectedMesh->m_rgcStrips[iAttrib]];
  226.  
  227.                             memcpy(m_pmcSelectedMesh->m_rgrgcStripCounts[iAttrib], pbufTemp->GetBufferPointer(), sizeof(DWORD)*m_pmcSelectedMesh->m_rgcStrips[iAttrib]);
  228.  
  229.                             GXRELEASE(pbufTemp);
  230.                             
  231.                         }
  232.                     }
  233.                 }
  234.  
  235.             }
  236. #endif
  237.             else if ( VK_SPACE == (int) wparam )
  238.             {
  239.                 ChangeAnimMode(!m_bAnimPaused);
  240.             }
  241.             else if ( VK_DELETE == (int) wparam )
  242.             {
  243.                 DeleteSelectedMesh();
  244.             }
  245.             else if ( 'e' == wparam || 'E' == wparam )
  246.             {
  247.                 ToggleEdgeMode();
  248.             }
  249.             else if ( 'w' == wparam || 'W' == wparam )
  250.             {
  251.                 ToggleWireframeMode();
  252.             }
  253.             else if ( 'c' == wparam || 'C' == wparam )
  254.             {
  255.                 ToggleCullMode();
  256.             }
  257.             else if ( 't' == wparam || 'T' == wparam )
  258.             {
  259.                 ToggleTextureMode();
  260.             }
  261.             else if ( 's' == wparam || 'S' == wparam )
  262.             {
  263.                 ToggleStripMode();
  264.             }
  265.             else if ( 'a' == wparam || 'A' == wparam )
  266.             {
  267.                 ToggleAdjacencyMode();
  268.             }
  269.             else if ( 'r' == wparam || 'R' == wparam )
  270.             {
  271.                 ToggleCreaseMode();
  272.             }
  273.             else if ( 'n' == wparam || 'N' == wparam )
  274.             {
  275.                 ToggleNormalsMode();
  276.             }
  277.             else if ( 'f' == wparam || 'F' == wparam )
  278.             {
  279.                 ToggleFaceSelectionMode();
  280.             }
  281.             else if ( 'v' == wparam || 'V' == wparam )
  282.             {
  283.                 ToggleVertexSelectionMode();
  284.             }
  285. #if 0
  286.             else if ( 'd' == wparam || 'D' == wparam )
  287.             {
  288.                 GXRELEASE(m_pmcSelectedMesh->pMesh);
  289.                 GXRELEASE(m_pmcSelectedMesh->ptmDrawMesh);
  290.                 D3DXCreateMeshFVF(30000, 3, D3DXMESH_MANAGED, D3DFVF_XYZ, m_pDevice, &m_pmcSelectedMesh->pMesh);
  291.                 m_pmcSelectedMesh->ptmDrawMesh = m_pmcSelectedMesh->pMesh;
  292.                 m_pmcSelectedMesh->pMesh->AddRef();
  293.  
  294.                 delete m_pmcSelectedMesh->rgdwAdjacency;
  295.                 m_pmcSelectedMesh->rgdwAdjacency = NULL;
  296.                 //m_pmcSelectedMesh->rgdwAdjacency = new DWORD[30000 * 3];
  297.                 //memset(m_pmcSelectedMesh->rgdwAdjacency, 0xff, 30000 * 3 * sizeof(DWORD));
  298.  
  299.                 UINT16 *pbIndices;
  300.                 PBYTE pbVertices;
  301.                 DWORD iFace;
  302.                 m_pmcSelectedMesh->pMesh->LockVertexBuffer(0, (LPVOID*)&pbVertices);
  303.                 m_pmcSelectedMesh->pMesh->LockIndexBuffer(0, (LPVOID*)&pbIndices);
  304.  
  305.                 *((D3DXVECTOR3*)pbVertices) = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
  306.                 pbVertices += sizeof(D3DXVECTOR3);
  307.                 *((D3DXVECTOR3*)pbVertices) = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
  308.                 pbVertices += sizeof(D3DXVECTOR3);
  309.                 *((D3DXVECTOR3*)pbVertices) = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
  310.                 pbVertices += sizeof(D3DXVECTOR3);
  311.  
  312.                 for (iFace = 0; iFace < 30000; iFace++)
  313.                 {
  314.                     if ((iFace % 1) == 0)
  315.                     {
  316.                         *pbIndices = 0;
  317.                         pbIndices++;
  318.  
  319.                         *pbIndices = 1;
  320.                         pbIndices++;
  321.  
  322.                         *pbIndices = 2;
  323.                         pbIndices++;
  324.                     }
  325.                     else
  326.                     {
  327.                         *pbIndices = 0;
  328.                         pbIndices++;
  329.  
  330.                         *pbIndices = 2;
  331.                         pbIndices++;
  332.  
  333.                         *pbIndices = 1;
  334.                         pbIndices++;
  335.                     }
  336.  
  337.                 }
  338.  
  339.                 m_pmcSelectedMesh->pMesh->UnlockVertexBuffer();
  340.                 m_pmcSelectedMesh->pMesh->UnlockIndexBuffer();
  341.             }
  342.             else if ( 'd' == wparam || 'D' == wparam )
  343.             {
  344.                 Displace();
  345.             }
  346.             else if ( '1' == wparam )
  347.             {
  348.                 if ((m_pmcSelectedMesh != NULL) && (m_pmcSelectedMesh->pMesh != NULL))
  349.                 {
  350.                     DWORD cFaces;
  351.                     DWORD *rgdwAttribs;
  352.                     DWORD iFace;
  353.  
  354.                     cFaces = m_pmcSelectedMesh->pMesh->GetNumFaces();
  355.                     
  356.                     m_pmcSelectedMesh->m_rgpfxAttributes = new LPD3DXEFFECT[cFaces];
  357.                     m_pmcSelectedMesh->m_cAttributeGroups = cFaces;
  358.                     m_pmcSelectedMesh->NumMaterials = cFaces;
  359.  
  360.                     memset(m_pmcSelectedMesh->m_rgpfxAttributes, 0, sizeof(LPD3DXEFFECT) * cFaces);
  361.  
  362.                     m_pmcSelectedMesh->pMesh->LockAttributeBuffer(0, &rgdwAttribs);
  363.  
  364.                     for (iFace = 0; iFace < cFaces; iFace++)
  365.                     {
  366.                         rgdwAttribs[iFace] = iFace;
  367.                     }
  368.  
  369.                     m_pmcSelectedMesh->pMesh->UnlockAttributeBuffer();
  370.  
  371.                     Optimize(D3DXMESHOPT_ATTRSORT);
  372.                 }
  373.             }
  374.             else if ('3' == wparam)
  375.             {
  376.                 if ((m_pmcSelectedMesh != NULL) && (m_pmcSelectedMesh->pMesh != NULL))
  377.                 {
  378.                     DXCrackFVF cfvf(m_pmcSelectedMesh->pMesh->GetFVF());
  379.                     PBYTE pbPoints;
  380.                     PBYTE pbCurVert;
  381.                     DWORD iVertex;
  382.  
  383.                     m_pmcSelectedMesh->pMesh->LockVertexBuffer(0, (LPVOID*)&pbPoints);
  384.  
  385.                     pbCurVert = pbPoints;
  386.                     for (iVertex = 0; iVertex < m_pmcSelectedMesh->pMesh->GetNumVertices(); iVertex++)
  387.                     {
  388.                         memcpy(cfvf.PvGetPosition(pbCurVert), cfvf.PuvGetTex1(pbCurVert) + 1, sizeof(D3DXVECTOR3));
  389.  
  390.                         pbCurVert += cfvf.m_cBytesPerVertex;
  391.                     }
  392.  
  393.                     m_pmcSelectedMesh->pMesh->UnlockVertexBuffer();
  394.                 }
  395.             }
  396.             else if ('2' == wparam)
  397.             {
  398.                 if ((m_pmcSelectedMesh != NULL) && (m_pmcSelectedMesh->pMesh != NULL))
  399.                 {
  400.                     LPD3DXMESH pMeshTemp;
  401.                     HRESULT hr;
  402.                     DWORD dwFVF;
  403.  
  404.                     dwFVF = m_pmcSelectedMesh->ptmDrawMesh->GetFVF();
  405.                     dwFVF &= ~D3DFVF_TEXCOUNT_MASK;
  406.                     dwFVF |= D3DFVF_TEX2 | D3DFVF_TEXCOORDSIZE3(1);
  407.  
  408.                     hr = m_pmcSelectedMesh->ptmDrawMesh->CloneMeshFVF(
  409.                                         m_pmcSelectedMesh->ptmDrawMesh->GetOptions(), 
  410.                                         dwFVF,
  411.                                         m_pDevice, &pMeshTemp);
  412.                     GXASSERT(!FAILED(hr));
  413.  
  414.                     GXRELEASE(m_pmcSelectedMesh->ptmDrawMesh);
  415.                     GXRELEASE(m_pmcSelectedMesh->pMesh);
  416.                     m_pmcSelectedMesh->ptmDrawMesh = pMeshTemp;
  417.                     m_pmcSelectedMesh->pMesh = pMeshTemp;
  418.                     pMeshTemp->AddRef();
  419.  
  420.                     DXCrackFVF cfvf(dwFVF);
  421.                     PBYTE pbPoints;
  422.                     PBYTE pbCurVert;
  423.                     DWORD iVertex;
  424.  
  425.                     m_pmcSelectedMesh->pMesh->LockVertexBuffer(0, (LPVOID*)&pbPoints);
  426.  
  427.                     pbCurVert = pbPoints;
  428.                     for (iVertex = 0; iVertex < m_pmcSelectedMesh->pMesh->GetNumVertices(); iVertex++)
  429.                     {
  430.                         memcpy(cfvf.PuvGetTex1(pbCurVert) + 1, cfvf.PvGetPosition(pbCurVert), sizeof(D3DXVECTOR3));
  431.                         memset(cfvf.PvGetPosition(pbCurVert), 0, sizeof(D3DXVECTOR3));
  432.  
  433.                         pbCurVert += cfvf.m_cBytesPerVertex;
  434.                     }
  435.  
  436.                     m_pmcSelectedMesh->pMesh->UnlockVertexBuffer();
  437.                 }
  438. #if 0
  439.                 if ((m_pmcSelectedMesh != NULL) && (m_pmcSelectedMesh->bNPatchMode))
  440.                 {
  441.                     DWORD cFaces;
  442.  
  443.                     cFaces = m_pmcSelectedMesh->pMesh->GetNumFaces();
  444.  
  445.                     GXRELEASE(m_pmcSelectedMesh->pMeshToTesselate);
  446.                     m_pmcSelectedMesh->bNPatchMode = FALSE;
  447.                     
  448.                     delete []m_pmcSelectedMesh->rgdwAdjacency;
  449.                     delete []m_pmcSelectedMesh->rgdwAdjacencyTesselate;
  450.  
  451.                     m_pmcSelectedMesh->rgdwAdjacency = new DWORD[cFaces * 3];
  452.  
  453.                     m_pmcSelectedMesh->pMesh->GenerateAdjacency(0.0f, m_pmcSelectedMesh->rgdwAdjacency);
  454.  
  455.                     AdjustScrollbar();
  456.  
  457.                     hr = m_pmcSelectedMesh->m_aoAdjacency.Init(m_pmcSelectedMesh->pMesh, m_pmcSelectedMesh->rgdwAdjacency);
  458.                     hr = m_pmcSelectedMesh->m_eoEdges.Init(m_pmcSelectedMesh->pMesh, m_pmcSelectedMesh->rgdwAdjacency);
  459.                 }
  460. #endif
  461.             }
  462.             else if ('U' == wparam)
  463.             {
  464.                 if (m_pmcSelectedMesh != NULL)
  465.                 {
  466.                     if (m_pmcSelectedMesh->bPMMeshMode)
  467.                     {
  468.                         m_pmcSelectedMesh->pPMMesh->OptimizeBaseLOD(D3DXMESHOPT_VERTEXCACHE, NULL);
  469.                         hr = m_pmcSelectedMesh->m_soStrips.Init(m_pmcSelectedMesh->ptmDrawMesh);
  470.                     }
  471.                 }
  472.             }
  473.             else if ('Y' == wparam)
  474.             {
  475.                 if (m_pmcSelectedMesh != NULL)
  476.                 {
  477.                     LPD3DXMESH pMeshTemp;
  478.                     LPDIRECT3DVERTEXBUFFER9 pVB1;
  479.                     LPDIRECT3DVERTEXBUFFER9 pVB2;
  480.  
  481.                     if (m_pmcSelectedMesh->bPMMeshMode)
  482.                     {
  483.                         if (0)
  484.                         {
  485.                             DWORD dwMinVertices = 1000, dwMaxVertices = 2000;
  486.  
  487.                             m_pmcSelectedMesh->pPMMesh->TrimByVertices(dwMinVertices, dwMaxVertices, NULL, NULL);
  488.  
  489.                             AdjustScrollbar();
  490.                         }
  491.                         else
  492.                         {
  493.                             LPD3DXPMESH pPMesh = m_pmcSelectedMesh->pPMMesh;
  494.  
  495.                             hr = m_pmcSelectedMesh->pPMMesh->Optimize(D3DXMESH_VB_WRITEONLY|D3DXMESH_MANAGED|D3DXMESHOPT_COMPACT|D3DXMESHOPT_ATTRSORT/*|D3DXMESHOPT_VERTEXCACHE*/, m_pmcSelectedMesh->rgdwAdjacency, NULL, NULL, &pMeshTemp);
  496.                             //hr = m_pmcSelectedMesh->ptmDrawMesh->CloneMeshFVF(
  497.                             //                    m_pmcSelectedMesh->ptmDrawMesh->GetOptions() /*| D3DXMESH_VB_SHARE*/, 
  498.                             //                    m_pmcSelectedMesh->ptmDrawMesh->GetFVF(),
  499.                             //                    m_pDevice, &pMeshTemp);
  500.                             GXASSERT(!FAILED(hr));
  501.  
  502.                             GXRELEASE(m_pmcSelectedMesh->pPMMesh);
  503.                             GXRELEASE(m_pmcSelectedMesh->ptmDrawMesh);
  504.  
  505.                             m_pmcSelectedMesh->ptmDrawMesh = pMeshTemp;
  506.                             m_pmcSelectedMesh->pMesh = pMeshTemp;
  507.                             pMeshTemp->AddRef();
  508.  
  509.                             m_pmcSelectedMesh->bPMMeshMode = false;
  510.                             AdjustScrollbar();
  511.  
  512.                             hr = m_pmcSelectedMesh->m_soStrips.Init(m_pmcSelectedMesh->pMesh);
  513.                         }
  514.                     }
  515.                     else
  516.                     {
  517.                         hr = m_pmcSelectedMesh->ptmDrawMesh->CloneMesh(
  518.                                             m_pmcSelectedMesh->ptmDrawMesh->GetOptions() | D3DXMESH_VB_SHARE, 
  519.                                             NULL,
  520.                                             m_pDevice, &pMeshTemp);
  521.                         GXASSERT(!FAILED(hr));
  522.  
  523.                         m_pmcSelectedMesh->ptmDrawMesh->GetVertexBuffer(&pVB1);
  524.                         pMeshTemp->GetVertexBuffer(&pVB2);
  525.  
  526.                         GXASSERT(pVB1 == pVB2);
  527.  
  528.                         GXRELEASE(pVB1);
  529.                         GXRELEASE(pVB2);
  530.                         GXRELEASE(pMeshTemp);
  531.                     }
  532.                 }
  533.             }
  534.             else if (('y' == wparam) || ('Y' == wparam))
  535.             {
  536.                 if (m_pmcSelectedMesh != NULL)
  537.                 {
  538.                     LPD3DXMESH pMeshTemp;
  539.                     if (m_pmcSelectedMesh->bPMMeshMode)
  540.                     {
  541.                         LPD3DXPMESH pPMesh = m_pmcSelectedMesh->pPMMesh;
  542.  
  543.                         hr = pPMesh->CloneMes(pPMesh->GetOptions(), NULL,
  544.                                                 m_pDevice, &pMeshTemp);
  545.                         GXASSERT(!FAILED(hr));
  546.  
  547.                         GXRELEASE(m_pmcSelectedMesh->pPMMesh);
  548.                         GXRELEASE(m_pmcSelectedMesh->ptmDrawMesh);
  549.  
  550.                         m_pmcSelectedMesh->ptmDrawMesh = pMeshTemp;
  551.                         m_pmcSelectedMesh->pMesh = pMeshTemp;
  552.                         pMeshTemp->AddRef();
  553.  
  554.                         m_pmcSelectedMesh->bPMMeshMode = false;
  555.                         AdjustScrollbar();
  556.  
  557.                         hr = D3DXComputeNormals(pMeshTemp, NULL);
  558.                         GXASSERT(!FAILED(hr));
  559.                     }
  560.                     else
  561.                     {
  562.                         pMeshTemp = m_pmcSelectedMesh->pMesh;
  563.  
  564.                         hr = D3DXComputeNormals(pMeshTemp, m_pmcSelectedMesh->rgdwAdjacency);
  565.                         GXASSERT(!FAILED(hr));
  566.                     }
  567.  
  568.                 }
  569.  
  570.                 m_pmcSelectedMesh->m_snNormals.Init(m_pmcSelectedMesh->pMesh, UNUSED32, m_pdeSelected->fRadius / 20.0f);
  571.             }
  572.             else if ('4' == wparam)
  573.             {
  574.                 if ((m_pmcSelectedMesh != NULL) && m_pmcSelectedMesh->bSimplifyMode)
  575.                 {
  576.                     char szBuf[1024];
  577.                     D3DXATTRIBUTEWEIGHTS AttribWeights;
  578.  
  579.                     m_pmcSelectedMesh->pSimpMesh->GetVertexAttributeWeights(&AttribWeights);
  580.  
  581.                     sprintf(szBuf, "Position: %f\r\n"
  582.                                    "Boundary: %f\r\n"
  583.                                    "Normal: %f\r\n"
  584.                                    "Diffuse: %f\r\n"
  585.                                    "Specular: %f\r\n"
  586.                                    "Tex[0]: %f\r\n"
  587.                                    "Tex[1]: %f\r\n"
  588.                                    "Tex[2]: %f\r\n"
  589.                                    "Tex[3]: %f\r\n"
  590.                                    "Tex[4]: %f\r\n"
  591.                                    "Tex[5]: %f\r\n"
  592.                                    "Tex[6]: %f\r\n"
  593.                                    "Tex[7]: %f\r\n", 
  594.                                    AttribWeights.Position, AttribWeights.Boundary,
  595.                                    AttribWeights.Normal, AttribWeights.Diffuse, AttribWeights.Specular,
  596.                                    AttribWeights.Tex[0], AttribWeights.Tex[1],
  597.                                    AttribWeights.Tex[2], AttribWeights.Tex[3],
  598.                                    AttribWeights.Tex[4], AttribWeights.Tex[5],
  599.                                    AttribWeights.Tex[6], AttribWeights.Tex[7]);
  600.  
  601.                     pvDialogData = szBuf;
  602.                     DialogBox(m_hInstance, (LPCTSTR) IDD_INFO, m_hwnd, (DLGPROC) DlgProcOutput);
  603.                 }
  604.             }
  605.             else if ('p' == wparam || 'P' == wparam )
  606.             {
  607.                 if ((m_pmcSelectedMesh != NULL) && m_pmcSelectedMesh->bSimplifyMode)
  608.                 {
  609.                     ID3DXPMesh *pPMesh;
  610.                     hr = m_pmcSelectedMesh->pSimpMesh->ClonePMesh(
  611.                                             m_pmcSelectedMesh->pSimpMesh->GetOptions(),
  612.                                             NULL,
  613.                                             m_pDevice,
  614.                                             NULL, &pPMesh);
  615.                     GXASSERT(!FAILED(hr));
  616.                     if (pPMesh != NULL)
  617.                     {
  618.                         m_pmcSelectedMesh->m_cMaxVerticesSoft = pPMesh->GetMaxVertices();
  619.                         m_pmcSelectedMesh->m_cMinVerticesSoft = pPMesh->GetMinVertices();
  620.                         m_pmcSelectedMesh->m_cNumVertices = pPMesh->GetNumVertices();
  621.  
  622.                         pPMesh->OptimizeBaseLOD(D3DXMESHOPT_VERTEXCACHE, NULL);
  623.  
  624.                         GXRELEASE(m_pmcSelectedMesh->pSimpMesh);
  625.                         m_pmcSelectedMesh->pPMMesh = pPMesh;
  626.  
  627.                         m_pmcSelectedMesh->ptmDrawMesh = pPMesh;
  628.                         pPMesh->AddRef();
  629.  
  630.                         m_pmcSelectedMesh->bSimplifyMode = false;
  631.                         m_pmcSelectedMesh->bPMMeshMode = true;
  632.  
  633.                         AdjustScrollbar();
  634.                     }
  635.  
  636.                 }
  637.             }
  638. #endif
  639. #ifdef OLD
  640.             else if ('3' == wparam)
  641.             {
  642.                 DXCrackFVF cfvf(D3DFVF_XYZ);
  643.                 DWORD dwFVF;
  644.                 LPD3DXMESH pMeshTemp;
  645.                 DWORD iVertex;
  646.                 PBYTE pvPoint;
  647.                 DWORD cVertices;
  648.                 PBYTE pvPoints;
  649.  
  650.                 // output mesh info to a temp file in a c format
  651.  
  652.                 // nothing to do, just return
  653.                 if ((m_pmcSelectedMesh != NULL) && (m_pmcSelectedMesh->pMesh != NULL))
  654.                 {
  655.                     GXASSERT( !(m_pmcSelectedMesh->pMesh->GetOptions() & D3DXMESH_32BIT) );
  656.                     DWORD *rgdwPointReps;
  657.                     FILE *file;
  658.                     WORD *pwIndices;
  659.                     DWORD iFace;
  660.                     DWORD cFaces;
  661.  
  662.                     file = fopen("c:\\tempmesh.txt", "w+");
  663.                     GXASSERT(file != NULL);
  664.  
  665.                     cVertices = m_pmcSelectedMesh->pMesh->GetNumVertices();
  666.                     cFaces= m_pmcSelectedMesh->pMesh->GetNumFaces();
  667.                     rgdwPointReps = new DWORD[cVertices];
  668.                     GXASSERT(rgdwPointReps != NULL);
  669.  
  670.                     cfvf = DXCrackFVF(m_pmcSelectedMesh->pMesh->GetFVF());
  671.  
  672.                     m_pmcSelectedMesh->pMesh->ConvertAdjacencyToPointReps(m_pmcSelectedMesh->rgdwAdjacency, rgdwPointReps);
  673.                 
  674.                     m_pmcSelectedMesh->pMesh->LockVertexBuffer(0, (LPVOID*)&pvPoints);
  675.                     m_pmcSelectedMesh->pMesh->LockIndexBuffer(0, (LPVOID*)&pwIndices);
  676.  
  677.                     fprintf(file, "static D3DXVECTOR3 teapotPositions[%d] = \n{\n", cVertices);
  678.                     for (iVertex = 0; iVertex < cVertices; iVertex++)
  679.                     {
  680.                         pvPoint = cfvf.GetArrayElem(pvPoints, iVertex);
  681.  
  682.                         fprintf(file, "    { %f, %f, %f },\n", cfvf.PvGetPosition(pvPoint)->x,
  683.                                                         cfvf.PvGetPosition(pvPoint)->y,
  684.                                                         cfvf.PvGetPosition(pvPoint)->z);
  685.                     }
  686.                     fprintf(file, "};\n");
  687.  
  688.                     fprintf(file, "static D3DXVECTOR3 teapotNormals[%d] = \n{\n", cVertices);
  689.                     for (iVertex = 0; iVertex < cVertices; iVertex++)
  690.                     {
  691.                         pvPoint = cfvf.GetArrayElem(pvPoints, iVertex);
  692.  
  693.                         fprintf(file, "    { %f, %f, %f },\n", cfvf.PvGetNormal(pvPoint)->x,
  694.                                                         cfvf.PvGetNormal(pvPoint)->y,
  695.                                                         cfvf.PvGetNormal(pvPoint)->z);
  696.                     }
  697.                     fprintf(file, "};\n");
  698.  
  699.                     fprintf(file, "static DWORD teapotPointReps[%d] = \n{\n", cVertices);
  700.                     for (iVertex = 0; iVertex < cVertices; iVertex++)
  701.                     {
  702.                         fprintf(file, "    %d,\n", rgdwPointReps[iVertex]);
  703.                     }
  704.                     fprintf(file, "};\n");
  705.  
  706.                     fprintf(file, "static WORD teapotIndices[%d] = \n{\n", cFaces * 3);
  707.                     for (iFace = 0; iFace < cFaces; iFace++)
  708.                     {
  709.                         fprintf(file, "    %d, %d, %d,\n", *(pwIndices), *(pwIndices + 1), *(pwIndices + 2));
  710.                         pwIndices += 3;
  711.                     }
  712.                     fprintf(file, "};\n");
  713.  
  714.                     m_pmcSelectedMesh->pMesh->UnlockVertexBuffer();
  715.                     m_pmcSelectedMesh->pMesh->UnlockIndexBuffer();
  716.  
  717.                     delete []rgdwPointReps;
  718.  
  719.                     fclose(file);
  720.                 }
  721.             }
  722. #endif
  723. #if 0
  724.             else if ('<' == wparam  || ',' == wparam )
  725.             {
  726.                 if (m_pmcSelectedMesh != NULL)
  727.                 {
  728.                     SimulateCacheStuff();
  729.                 }
  730.             }
  731.             else if ('+' == wparam)
  732.             {
  733.                 if (m_pmcSelectedMesh != NULL) 
  734.                 {
  735.                     RemoveAllMeshesExceptSelected();
  736.                 }
  737.             }
  738. #endif
  739.             else if ('z' == wparam || 'Z' == wparam )
  740.             {
  741.                 SetNumVertices(1, true /*absolute*/);
  742.             }
  743.             else if ('x' == wparam || 'X' == wparam )
  744.             {
  745.                 SetNumVertices(0x7fffffff, true /*absolute*/);
  746.             }
  747.             else if ( 'q' == wparam || 'Q' == wparam )
  748.             {
  749.                 ToggleNPatchEdgeMode();
  750.             }
  751. #if 0
  752.             else if ( '8' == wparam )
  753.             {
  754.                 if ((m_pmcSelectedMesh != NULL) && (m_pmcSelectedMesh->bPMMeshMode))
  755.                 {
  756.                     unsigned short *pbIndices;
  757.  
  758.                     DWORD cFaces = m_pmcSelectedMesh->pPMMesh->GetMaxFaces();
  759.                     DWORD *rgdwAdjacencySrc = new DWORD[cFaces * 3];
  760.                     DWORD *rgdwAdjacencyNew = new DWORD[cFaces * 3];
  761.                     DWORD *rgdwPReps = new DWORD[m_pmcSelectedMesh->pPMMesh->GetMaxVertices()];
  762.                     m_pmcSelectedMesh->pPMMesh->GetAdjacency(rgdwAdjacencySrc);
  763.  
  764.                     m_pmcSelectedMesh->pPMMesh->ConvertAdjacencyToPointReps(rgdwAdjacencySrc, rgdwPReps);
  765.                     m_pmcSelectedMesh->pPMMesh->ConvertPointRepsToAdjacency(rgdwPReps, rgdwAdjacencyNew);
  766.  
  767.                     m_pmcSelectedMesh->pPMMesh->LockIndexBuffer(D3DLOCK_READONLY, (LPVOID*)&pbIndices);
  768.  
  769.                     for (DWORD iFace = 0; iFace < cFaces; iFace++)
  770.                     {
  771.                         for (DWORD iPoint = 0; iPoint < 3; iPoint++)
  772.                         {
  773.                             GXASSERT(rgdwAdjacencySrc[iFace * 3 + iPoint] == rgdwAdjacencyNew[iFace * 3 + iPoint]);
  774.                         }
  775.                     }
  776.  
  777.                     m_pmcSelectedMesh->pPMMesh->UnlockIndexBuffer();
  778.                 }
  779.                 
  780.             }
  781.             else if ('9' == wparam)
  782.             {
  783.                 if (m_pmcSelectedMesh != NULL)
  784.                 {
  785.                     unsigned short *pwIndices;
  786.                     D3DXVECTOR3 *rgvVertices;
  787.  
  788.                     GXRELEASE(m_pmcSelectedMesh->ptmDrawMesh);
  789.                     GXRELEASE(m_pmcSelectedMesh->pMesh);
  790.                     D3DXCreateMeshFVF(4, 6, D3DXMESH_MANAGED, D3DFVF_XYZ, m_pDevice, &m_pmcSelectedMesh->pMesh);
  791.  
  792.                     m_pmcSelectedMesh->ptmDrawMesh = m_pmcSelectedMesh->pMesh;
  793.                     m_pmcSelectedMesh->pMesh->AddRef();
  794.  
  795.                     m_pmcSelectedMesh->pMesh->LockIndexBuffer(0, (LPVOID*)&pwIndices);
  796.                     m_pmcSelectedMesh->pMesh->LockVertexBuffer(0, (LPVOID*)&rgvVertices);
  797.  
  798.                     rgvVertices[0] = D3DXVECTOR3(-1.0, 1.0, 0.0);
  799.                     rgvVertices[1] = D3DXVECTOR3(-1.0, 0.0, 0.0);
  800.                     rgvVertices[2] = D3DXVECTOR3( 0.0, 1.0, 0.0);
  801.                     rgvVertices[3] = D3DXVECTOR3( 0.0, 0.0, 0.0);
  802.                     rgvVertices[4] = D3DXVECTOR3( 1.0, 1.0, 0.0);
  803.                     rgvVertices[5] = D3DXVECTOR3( 1.0, 0.0, 0.0);
  804.  
  805.                     pwIndices[0] = 0;
  806.                     pwIndices[1] = 1;
  807.                     pwIndices[2] = 2;
  808.                     pwIndices[3] = 2;
  809.                     pwIndices[4] = 1;
  810.                     pwIndices[5] = 3;
  811.  
  812.                     pwIndices[6] = 2;
  813.                     pwIndices[7] = 3;
  814.                     pwIndices[8] = 4;
  815.                     pwIndices[9] = 4;
  816.                     pwIndices[10] = 3;
  817.                     pwIndices[11] = 5;
  818.  
  819.                     m_pmcSelectedMesh->pMesh->UnlockIndexBuffer();
  820.                     m_pmcSelectedMesh->pMesh->UnlockVertexBuffer();
  821.  
  822.  
  823.                     m_pmcSelectedMesh->rgdwAdjacency[0] = UNUSED32;
  824.                     m_pmcSelectedMesh->rgdwAdjacency[1] = 1;
  825.                     m_pmcSelectedMesh->rgdwAdjacency[2] = UNUSED32;
  826.                     m_pmcSelectedMesh->rgdwAdjacency[3] = 0;
  827.                     m_pmcSelectedMesh->rgdwAdjacency[4] = UNUSED32;
  828.                     m_pmcSelectedMesh->rgdwAdjacency[5] = UNUSED32;
  829.  
  830.                     m_pmcSelectedMesh->rgdwAdjacency[6] = UNUSED32;
  831.                     m_pmcSelectedMesh->rgdwAdjacency[7] = 3;
  832.                     m_pmcSelectedMesh->rgdwAdjacency[8] = UNUSED32;
  833.                     m_pmcSelectedMesh->rgdwAdjacency[9] = 2;
  834.                     m_pmcSelectedMesh->rgdwAdjacency[10] = UNUSED32;
  835.                     m_pmcSelectedMesh->rgdwAdjacency[11] = UNUSED32;
  836.  
  837.                     m_pmcSelectedMesh->UpdateViews(m_pdeSelected);
  838.                 }
  839.             }
  840.             else if ('8' == wparam)
  841.             {
  842.                 TesselateFrame(m_pframeSelected);
  843.             }
  844.             else if ('9' == wparam)
  845.             {
  846.                 SplitMesh();
  847.             }
  848. #endif
  849.             else if ('i' == wparam || 'I' == wparam)
  850.             {
  851.                 if (m_bVertexSelectionMode && (m_dwVertexSelected != UNUSED32))
  852.                 {
  853.                     DialogBox(m_hInstance, (LPCTSTR) IDD_VERTEXINFO, m_hwnd, (DLGPROC) DlgProcVertexInfo);
  854.                 }
  855.                 else if (m_bFaceSelectionMode && (m_dwFaceSelected != UNUSED32))
  856.                 {
  857.                     DialogBox(m_hInstance, (LPCTSTR) IDD_FACEINFO, m_hwnd, (DLGPROC) DlgProcFaceInfo);
  858.                 }
  859.                 else if (m_pmcSelectedMesh != NULL) // show mesh stats
  860.                 {
  861.                     DialogBox(m_hInstance, (LPCTSTR) IDD_INFO, m_hwnd, (DLGPROC) DlgProcMeshInfo);
  862.                 }
  863.             }
  864.             return 0;
  865.  
  866.         case WM_VSCROLL:
  867.             {
  868.                 if ((m_pmcSelectedMesh != NULL) && (m_pmcSelectedMesh->bTesselateMode || m_pmcSelectedMesh->bNPatchMode))
  869.                 {
  870.                     int min, max;
  871.                     int cLevelNew = m_pmcSelectedMesh->cTesselateLevel;
  872.                     GetScrollRange(hwnd, SB_VERT, &min, &max);
  873.  
  874.                     int delta = 1;
  875.  
  876.                     switch (LOWORD(wparam))
  877.                     {
  878.                     case SB_THUMBPOSITION:
  879.                         cLevelNew = min + max - HIWORD(wparam);
  880.                         break;
  881.                     case SB_LINEUP:
  882.                         cLevelNew += delta;
  883.                         break;
  884.                     case SB_LINEDOWN:
  885.                         if (cLevelNew > delta)
  886.                             cLevelNew -= delta;
  887.                         else
  888.                             cLevelNew = 0;
  889.                         break;
  890.                     case SB_PAGEUP:
  891.                         cLevelNew += 2*delta;
  892.                         break;
  893.                     case SB_PAGEDOWN:
  894.                         if (cLevelNew > 2*delta)
  895.                             cLevelNew -= 2*delta;
  896.                         else
  897.                             cLevelNew = 0;
  898.                         break;
  899.                     case SB_THUMBTRACK:
  900.                         cLevelNew = min + max - HIWORD(wparam);
  901.                         break;
  902.  
  903.                     case SB_ENDSCROLL:
  904.                         return 0;
  905.  
  906.                     case SB_BOTTOM:
  907.                         //vertices = min;
  908.                         //break;
  909.                     case SB_TOP:
  910.                         //vertices = max;
  911.                         //break;
  912.                     default:
  913.                         return 0;
  914.                     }
  915.  
  916.                     SMeshContainer *pmc = m_pframeSelected->pmcMesh;
  917.  
  918.                     while (pmc != NULL)
  919.                     {
  920.                         pmc->cTesselateLevel = cLevelNew;
  921.                         Tesselate(pmc, FALSE);
  922.  
  923.                         pmc = (SMeshContainer*)pmc->pNextMeshContainer;
  924.                     }
  925.                 }
  926.  
  927.                 if ((m_pmcSelectedMesh != NULL) && m_pmcSelectedMesh->pPMMesh && m_pmcSelectedMesh->bPMMeshMode)
  928.                 {
  929.                     DWORD vertices;
  930.                     int min, max;
  931.                     DWORD cMaxVertices, cMinVertices;
  932.                     BOOL bUpdateViews = TRUE;
  933.  
  934.                     GetScrollRange(hwnd, SB_VERT, &min, &max);
  935.                     vertices = m_pmcSelectedMesh->pPMMesh->GetNumVertices();
  936. //                    DWORD delta = (max - min) / 500;
  937.                     DWORD delta = (max - min) / 500;
  938.                     if (delta == 0)
  939.                         delta = 1;
  940.  
  941.                     switch (LOWORD(wparam))
  942.                     {
  943.                     case SB_THUMBPOSITION:
  944.                         vertices = min + max - HIWORD(wparam);
  945.                         break;
  946.                     case SB_LINEUP:
  947.                         vertices += delta;
  948.                         break;
  949.                     case SB_LINEDOWN:
  950.                         if (vertices > delta)
  951.                             vertices -= delta;
  952.                         else
  953.                             vertices = 0;
  954.                         break;
  955.                     case SB_PAGEUP:
  956.                         vertices += 5*delta;
  957.                         break;
  958.                     case SB_PAGEDOWN:
  959.                         if (vertices > 5*delta)
  960.                             vertices -= 5*delta;
  961.                         else
  962.                             vertices = 0;
  963.                         break;
  964.                     case SB_THUMBTRACK:
  965.                         vertices = min + max - HIWORD(wparam);
  966.                         bUpdateViews = FALSE;
  967.                         break;
  968.  
  969.                     case SB_ENDSCROLL:
  970.                         return 0;
  971.  
  972.                     case SB_BOTTOM:
  973.                         //vertices = min;
  974.                         //break;
  975.                     case SB_TOP:
  976.                         //vertices = max;
  977.                         //break;
  978.                     default:
  979.                         return 0;
  980.                     }
  981.                     if (vertices < (DWORD)min) vertices=min;
  982.                     if (vertices > (DWORD)max) vertices=max;
  983.                     cMaxVertices = m_pmcSelectedMesh->pPMMesh->GetMaxVertices();
  984.                     cMinVertices = m_pmcSelectedMesh->pPMMesh->GetMinVertices();
  985.                     if (vertices < cMinVertices) vertices=cMinVertices;
  986.                     if (vertices > cMaxVertices) vertices=cMaxVertices;
  987.  
  988.                     if (vertices < m_pmcSelectedMesh->m_cMinVerticesSoft) 
  989.                         vertices = m_pmcSelectedMesh->m_cMinVerticesSoft;
  990.  
  991.                     if (vertices > m_pmcSelectedMesh->m_cMaxVerticesSoft) 
  992.                         vertices = m_pmcSelectedMesh->m_cMaxVerticesSoft;
  993.  
  994.                     m_pmcSelectedMesh->pPMMesh->SetNumVertices(vertices);
  995.                     m_pmcSelectedMesh->ptmDrawMesh->GetAttributeTable(m_pmcSelectedMesh->m_rgaeAttributeTable, NULL);
  996.                     SetScrollPos(hwnd, SB_VERT, min + max - vertices, TRUE);
  997.  
  998.                     if (bUpdateViews)
  999.                     {
  1000.                         m_pmcSelectedMesh->pPMMesh->GetAdjacency(m_pmcSelectedMesh->rgdwAdjacency);
  1001.                         m_pmcSelectedMesh->UpdateViews(m_pdeSelected);
  1002.                     }
  1003.  
  1004.                     if (m_dwFaceSelected != UNUSED32)
  1005.                     {
  1006.         
  1007.                         if ((m_dwVertexSelected >= m_pmcSelectedMesh->m_rgaeAttributeTable[m_dwFaceSelectedAttr].VertexStart + m_pmcSelectedMesh->m_rgaeAttributeTable[m_dwFaceSelectedAttr].VertexCount)
  1008.                               || (m_dwFaceSelected >= m_pmcSelectedMesh->m_rgaeAttributeTable[m_dwFaceSelectedAttr].FaceStart + m_pmcSelectedMesh->m_rgaeAttributeTable[m_dwFaceSelectedAttr].FaceCount))
  1009.                         {
  1010.                             m_dwVertexSelected = UNUSED32;
  1011.                             m_dwFaceSelected = UNUSED32;
  1012.                             m_dwFaceSelectedAttr = UNUSED32;
  1013.                         }
  1014.                     }
  1015.  
  1016.                     Draw();
  1017.                 }
  1018.             }
  1019.             return 0;
  1020.         case WM_ACTIVATEAPP:
  1021. //            bActive = (wparam) ? true : false;
  1022.             break;
  1023.  
  1024.         case WM_SIZE:
  1025.             GetClientRect( hwnd, &r );
  1026.  
  1027.             // setup the client rect size, used for frame rate info
  1028.             m_sizeClient.cx = r.right - r.left;
  1029.             m_sizeClient.cy = r.bottom - r.top;
  1030.  
  1031.             m_abArcBall.SetWindow(r.right, r.bottom, 0.85f);
  1032.  
  1033.             if (m_pdeSelected != NULL)
  1034.                 SetProjectionMatrix();
  1035.  
  1036.             SendMessage(m_hwndStatus, WM_SIZE, 0, 0);
  1037.             SendMessage(m_hwndToolbar, WM_SIZE, 0, 0);
  1038.  
  1039.             INT lpParts[x_cStatusBarSizes + 1];// = {280, 370, 430, 500, 560, 640};
  1040.             DWORD iCur;
  1041.             INT iPart;
  1042.             iCur = m_sizeClient.cx;
  1043.             for (iPart = x_cStatusBarSizes - 1; iPart >= 0; iPart--)
  1044.             {
  1045.                 lpParts[iPart+1] = iCur;
  1046.                 iCur -= x_rgStatusBarSizes[iPart];
  1047.             }
  1048.             lpParts[0] = iCur;
  1049.  
  1050.             SendMessage(m_hwndStatus, SB_SETPARTS, (WPARAM) x_cStatusBarSizes+1, (LPARAM) lpParts); 
  1051.  
  1052.             break;
  1053.  
  1054.         case WM_COMMAND:
  1055.             if ( 1 == HIWORD(wparam) )
  1056.             {
  1057. #if 0
  1058.                 switch ( LOWORD(wparam) )
  1059.                 {
  1060.                     case ID_FULLSCREEN:
  1061.                         bFullScreen = ! bFullScreen;
  1062.                         bInitiatedModeChange = true;
  1063.  
  1064.                         if ( bFullScreen )
  1065.                         {
  1066.                             // going to fullscreen
  1067.                             GetWindowRect( hwnd, &m_rWindowedRect );
  1068.  
  1069.                         }
  1070.                         else
  1071.                         {
  1072.                             bInitiatedModeChange = true;
  1073.                         }
  1074.  
  1075.                         ReleaseTextures();
  1076.  
  1077.                         GXRELEASE( m_pDevice );
  1078.                         Initialize( hwnd );
  1079.                         PrepareToDraw( );
  1080.  
  1081.                         ReloadTextures( );
  1082.  
  1083.                         if ( ! bFullScreen )
  1084.                         {
  1085.                             RECT& r = m_rWindowedRect;
  1086.                             SetWindowPos(hwnd, HWND_NOTOPMOST, r.left, r.top, r.right-r.left, r.bottom-r.top, SWP_NOACTIVATE );
  1087.  
  1088.                         }
  1089.  
  1090.                         bInitiatedModeChange = false;
  1091.                         break;
  1092.                 }
  1093. #endif
  1094.             }
  1095.             if ( 0 == HIWORD(wparam) )
  1096.             {
  1097.                 if ((LOWORD(wparam) >= ID_ANIMATION_1) && (LOWORD(wparam) <= ID_ANIMATION_50))
  1098.                 {
  1099.                         SwitchToAnimationSet(LOWORD(wparam) - ID_ANIMATION_1);
  1100.                 }
  1101. #if 0
  1102.                 if ((LOWORD(wparam) >= ID_MESH_1) && (LOWORD(wparam) <= ID_MESH_9))
  1103.                 {
  1104.                         SwitchToMeshID(LOWORD(wparam));
  1105.                 }
  1106. #endif
  1107.  
  1108.                 switch ( LOWORD(wparam) )
  1109.                 {
  1110.                     case ID_FILE_EXIT:
  1111.                         PostQuitMessage(0);
  1112.                         return 0;
  1113.  
  1114.                     case ID_FILE_OPENMESH:
  1115.                         LoadNewMesh();
  1116.                         return 0;
  1117.  
  1118.                     case ID_FILE_LOADPMESH:
  1119.                         LoadNewProgressiveMesh();
  1120.                         return 0;
  1121.  
  1122.                     case ID_FILE_SAVEMESH:
  1123.                         SaveMesh();
  1124.                         //SavePMesh();
  1125.                         return 0;
  1126.  
  1127.                     case ID_FILE_CLOSEMESH:
  1128.                         DeleteSelectedMesh();
  1129.                         break;
  1130.  
  1131.                     case ID_FILE_CLOSENONSELECTED:
  1132.                         if (m_pmcSelectedMesh != NULL) 
  1133.                         {
  1134.                             RemoveAllMeshesExceptSelected();
  1135.                         }
  1136.                         break;
  1137.  
  1138.  
  1139.                     case ID_SIMPLIFY_GENERATEPM:
  1140.                         // as long as it is not a PMesh, try to generate a PM
  1141.                         //   normal meshes will get converted to a simplification mesh
  1142.                         //   before attempting simplification
  1143.                         if ((m_pmcSelectedMesh != NULL) && (m_pmcSelectedMesh->bSimplifyMode || (m_pmcSelectedMesh->pMesh != NULL)))
  1144.                         {
  1145.                             GeneratePM();
  1146.                         }
  1147.                         return 0;
  1148.  
  1149.                     case ID_SIMPLIFY_SIMPLIFY:
  1150.                         if (m_pmcSelectedMesh != NULL)
  1151.                         {
  1152.                             if (!m_pmcSelectedMesh->bSimplifyMode && !m_pmcSelectedMesh->bPMMeshMode && (m_pmcSelectedMesh->pMesh != NULL))
  1153.                             {
  1154.                                 hr = ConvertMeshToSimplify();
  1155.                                 if (FAILED(hr)) // check for cancel or other failures
  1156.                                     break;
  1157.                             }
  1158.  
  1159.                             if (m_pmcSelectedMesh->bSimplifyMode || m_pmcSelectedMesh->bPMMeshMode)
  1160.                             {
  1161.                                 DialogBox(m_hInstance, (LPCTSTR) IDD_SIMPLIFY, hwnd, (DLGPROC) DlgProcSimplify);
  1162.                             }
  1163.                         }
  1164.                         break;
  1165.  
  1166.                     case ID_SIMPLIFY_SIMPLIFYFACES:
  1167.                         if (m_pmcSelectedMesh != NULL)
  1168.                         {
  1169.                             if (!m_pmcSelectedMesh->bSimplifyMode && !m_pmcSelectedMesh->bPMMeshMode && (m_pmcSelectedMesh->pMesh != NULL))
  1170.                             {
  1171.                                 hr = ConvertMeshToSimplify();
  1172.                                 if (FAILED(hr)) // check for cancel or other failures
  1173.                                     break;
  1174.                             }
  1175.  
  1176.                             if (m_pmcSelectedMesh->bSimplifyMode || m_pmcSelectedMesh->bPMMeshMode)
  1177.                             {
  1178.                                 DialogBox(m_hInstance, (LPCTSTR) IDD_SIMPLIFYFACES, hwnd, (DLGPROC) DlgProcSimplifyFaces);
  1179.                             }
  1180.                         }
  1181.                         break;
  1182.                     case ID_SIMPLIFY_TESTSIMPLIFY:
  1183.                         TestSimplify();
  1184.                         break;
  1185.  
  1186.                     case ID_SIMPLIFY_SETSOFTMIN:
  1187.                         SetSoftMinLOD();
  1188.                         break;
  1189.  
  1190.                     case ID_SIMPLIFY_SETSOFTMAX:
  1191.                         SetSoftMaxLOD();
  1192.                         break;
  1193.  
  1194.                     case ID_SIMPLIFY_RESETSOFTMIN:
  1195.                         ResetSoftMinLOD();
  1196.                         break;
  1197.  
  1198.                     case ID_SIMPLIFY_RESETSOFTMAX:
  1199.                         ResetSoftMaxLOD();
  1200.                         break;
  1201.  
  1202.                     case ID_SIMPLIFY_TRIM:
  1203.                         TrimPMeshToSoftLimits();
  1204.                         break;
  1205.  
  1206.                     case ID_SIMPLIFY_SNAPSHOT:
  1207.                         SnapshotSelected();
  1208.                         break;
  1209.  
  1210.                     case ID_OPTIONS_PROPERTIES:
  1211.                         if (m_pmcSelectedMesh != NULL)
  1212.                             DialogBox(m_hInstance, (LPCTSTR) IDD_MESHPROPERTIES, hwnd, (DLGPROC) DlgProcProperties);
  1213.                         break;
  1214.  
  1215.                     case ID_OPTIONS_COMPACT:
  1216.                         Optimize(D3DXMESHOPT_COMPACT);
  1217.                         break;
  1218.  
  1219.                     case ID_OPTIONS_ATTRSORT:
  1220.                         Optimize(D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT);
  1221.                         break;
  1222.  
  1223.                     case ID_OPTIONS_STRIPREORDER:
  1224.                         Optimize(D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_STRIPREORDER);
  1225.                         break;
  1226.  
  1227.                     case ID_OPTIONS_VERTEXCACHE:
  1228.                         Optimize(D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE);
  1229.                         break;
  1230.  
  1231.                     case ID_OPTIMIZE_SIMULATE:
  1232.                         DisplayCacheBehavior();
  1233.                         break;
  1234.  
  1235.                     case ID_OPTIONS_TEXTURE:
  1236.                         ToggleTextureMode();
  1237.                         break;
  1238.  
  1239.                     case ID_OPTIONS_NOSELECTION:
  1240.                         ToggleNoSelectionMode();
  1241.                         break;
  1242.  
  1243.                     case ID_OPTIONS_FACESELECTION:
  1244.                         ToggleFaceSelectionMode();
  1245.                         break;
  1246.  
  1247.                     case ID_OPTIONS_VERTEXSELECTION:
  1248.                         ToggleVertexSelectionMode();
  1249.                         break;
  1250.  
  1251.                     case ID_OPTIONS_MESHSELECTION:
  1252.                         ToggleMeshSelectionMode();
  1253.                         break;
  1254.  
  1255.                     case ID_OPTIONS_WELDVERTICES:
  1256.                         WeldVertices();
  1257.                         break;
  1258.  
  1259.                     case ID_NPATCHES_NPATCH:
  1260.                         TesselateFrame(m_pframeSelected);
  1261.                         break;
  1262.  
  1263.                     case ID_NPATCHES_SNAPSHOT:
  1264.                         SnapshotSelected();
  1265.                         break;
  1266.  
  1267.                     case ID_NPATCHES_EDGEMODE:
  1268.                         ToggleNPatchEdgeMode();
  1269.                         break;
  1270.  
  1271.                     case ID_OPTIONS_SPLITMESH:
  1272.                         SplitMesh();
  1273.                         break;
  1274.  
  1275.                     case ID_MESHOPS_COLLAPSE:
  1276.                         MergeMeshes();
  1277.                         break;
  1278.  
  1279.                     case ID_MESHOPS_COMPUTENORMALS:
  1280.                         ComputeNormals();
  1281.                         break;
  1282.  
  1283.                     case ID_MESHOPS_VALIDATEMESH:
  1284.                         ValidateMesh();
  1285.                         break;
  1286.  
  1287.                     case ID_OPTIONS_APPLYDISPLACEMENT:
  1288.                         Displace();
  1289.                         break;
  1290.  
  1291.                     case ID_OPTIONS_RESETMATRICES:
  1292.                         if ((m_pdeSelected != NULL) && (m_pdeSelected->pframeRoot != NULL))
  1293.                         {
  1294.                             m_pdeSelected->pframeRoot->ResetMatrix();
  1295.                         }
  1296.  
  1297.                         break;
  1298.  
  1299.                     case ID_OPTIONS_TREEVIEW:
  1300.                         ToggleTreeView();
  1301.                         break;
  1302.  
  1303.                     case ID_D3D_LIGHTING:
  1304.                         ToggleLightMode();
  1305.                         break;
  1306.  
  1307.                     case ID_D3D_CULL:
  1308.                         ToggleCullMode();
  1309.                         break;
  1310.  
  1311.                     case ID_D3D_EDGEMODE:
  1312.                         ToggleEdgeMode();
  1313.                         break;
  1314.  
  1315.                     case ID_D3D_STRIPMODE:
  1316.                         ToggleStripMode();
  1317.                         break;
  1318.  
  1319.                     case ID_D3D_ADJACENCYMODE:
  1320.                         ToggleAdjacencyMode();
  1321.                         break;
  1322.  
  1323.                     case ID_D3D_CREASEMODE:
  1324.                         ToggleCreaseMode();
  1325.                         break;
  1326.  
  1327.                     case ID_D3D_SHOWNORMALS:
  1328.                         ToggleNormalsMode();
  1329.                         break;
  1330.  
  1331.                     case ID_D3D_SHOWTEX0:
  1332.                     case ID_D3D_SHOWTEX1:
  1333.                     case ID_D3D_SHOWTEX2:
  1334.                     case ID_D3D_SHOWTEX3:
  1335.                     case ID_D3D_SHOWTEX4:
  1336.                     case ID_D3D_SHOWTEX5:
  1337.                     case ID_D3D_SHOWTEX6:
  1338.                     case ID_D3D_SHOWTEX7:
  1339.                         ToggleShowTexCoord(LOWORD(wparam)-ID_D3D_SHOWTEX0);
  1340.                         break;
  1341.  
  1342.                     case ID_D3D_WIREFRAME:
  1343.                         ToggleWireframeMode();
  1344.                         break;
  1345.  
  1346.                     case ID_D3D_SOLID:
  1347.                         ToggleSolidMode();
  1348.                         break;
  1349.  
  1350.                     case ID_ANIMATION_LOAD:
  1351.                         AddAnimation();
  1352.                         break;
  1353.  
  1354.                     case ID_VIEW_PLAYANIM:
  1355.                         ChangeAnimMode(FALSE);
  1356.                         break;
  1357.  
  1358.                     case ID_VIEW_PAUSEANIM:
  1359.                         ChangeAnimMode(TRUE);
  1360.                         break;
  1361.                     case ID_VIEW_PLAYBACKSPEED:
  1362.                         TogglePlaybackSpeed();
  1363.                         break;
  1364.  
  1365.                     case ID_D3D_SOFTWARESKIN:
  1366.                         ChangeSkinningMode(SOFTWARE);
  1367.                         break;
  1368.  
  1369.                     case ID_D3D_NONINDEXED:
  1370.                         ChangeSkinningMode(D3DNONINDEXED);
  1371.                         break;
  1372.  
  1373.                     case ID_D3D_INDEXED:
  1374.                         ChangeSkinningMode(D3DINDEXED);
  1375.                         break;
  1376.  
  1377.                     case ID_SHAPE_SELECTFONT:
  1378.                         SelectTextFont();
  1379.                         break;
  1380.  
  1381.                     case ID_SHAPE_TEXT:
  1382.                         CreateText();
  1383.                         break;
  1384.  
  1385.                     case ID_SHAPE_POLYGON:
  1386.                         CreatePolygon();
  1387.                         break;
  1388.  
  1389.                     case ID_SHAPE_BOX:
  1390.                         CreateBox();
  1391.                         break;
  1392.  
  1393.                     case ID_SHAPE_CYLINDER:
  1394.                         CreateCylinder();
  1395.                         break;
  1396.  
  1397.                     case ID_SHAPE_TORUS:
  1398.                         CreateTorus();
  1399.                         break;
  1400.  
  1401.                     case ID_SHAPE_TEAPOT:
  1402.                         CreateTeapot();
  1403.                         break;
  1404.  
  1405.                     case ID_SHAPE_SPHERE:
  1406.                         CreateSphere();
  1407.                         break;
  1408.  
  1409.                     case ID_SHAPE_CONE:
  1410.                         CreateCone();
  1411.                         break;
  1412.  
  1413.                     case ID_HELP_ABOUT:
  1414.                         DialogBox(m_hInstance, (LPCTSTR) IDD_ABOUTBOX, hwnd, (DLGPROC) DlgProcAbout);
  1415.                         break;
  1416.  
  1417.                     case ID_OPTIONS_INFO:
  1418.                         if (m_bVertexSelectionMode && (m_dwVertexSelected != UNUSED32))
  1419.                         {
  1420.                             DialogBox(m_hInstance, (LPCTSTR) IDD_VERTEXINFO, m_hwnd, (DLGPROC) DlgProcVertexInfo);
  1421.                         }
  1422.                         else if (m_bFaceSelectionMode && (m_dwFaceSelected != UNUSED32))
  1423.                         {
  1424.                             DialogBox(m_hInstance, (LPCTSTR) IDD_FACEINFO, m_hwnd, (DLGPROC) DlgProcFaceInfo);
  1425.                         }
  1426.                         else if (m_pmcSelectedMesh != NULL) // show mesh stats
  1427.                         {
  1428.                             DialogBox(m_hInstance, (LPCTSTR) IDD_INFO, m_hwnd, (DLGPROC) DlgProcMeshInfo);
  1429.                         }
  1430.                         break;
  1431.  
  1432.                 }
  1433.             }
  1434.             break;
  1435.         /*
  1436.          * Pause and unpause the app when entering/leaving the menu
  1437.          */
  1438.         case WM_ENTERMENULOOP:
  1439.             PauseDrawing();
  1440.             break;
  1441.         case WM_EXITMENULOOP:
  1442.             RestartDrawing();
  1443.             break;
  1444.         case WM_ACTIVATE:
  1445.             {
  1446.                 DWORD fActive = LOWORD(wparam);
  1447.  
  1448.                 if (fActive == WA_INACTIVE)
  1449.                     PauseDrawing();
  1450.                 else
  1451.                     RestartDrawing();
  1452.             }
  1453.             break;
  1454.         case WM_CLOSE:
  1455.             PostQuitMessage(0);
  1456.             return 0;
  1457.  
  1458.         case WM_RBUTTONDOWN:
  1459.         case WM_MBUTTONDOWN:
  1460.             m_vCurMousePosition.x = (float)LOWORD(lparam);  // horizontal position of cursor
  1461.             m_vCurMousePosition.y = (float)HIWORD(lparam);  // vertical position of cursor
  1462.  
  1463.             break;
  1464.  
  1465.         case WM_LBUTTONDOWN:
  1466.             UINT bControl;
  1467.             bControl = GetAsyncKeyState(VK_CONTROL) & 0x8000;
  1468.  
  1469.             m_abArcBall.BeginDrag(LOWORD(lparam), HIWORD(lparam));
  1470.  
  1471.             // update selection change if not editing normals
  1472.             if (!(m_bVertexSelectionMode && (m_dwVertexSelected != UNUSED32) 
  1473.                             && m_bNormalsMode && bControl && (wparam & MK_LBUTTON)))
  1474.             {
  1475.                 SelectionChange(LOWORD(lparam), HIWORD(lparam));
  1476.             }
  1477.  
  1478.             SetCapture(m_hwnd);
  1479.  
  1480.             break;
  1481.  
  1482.         case WM_LBUTTONUP:
  1483.  
  1484.             // if re-tesselated during mouse move due to normal modification.  Re-tesselate now to re-init views
  1485.             if (m_bUpdatedNormalDuringMouseMove && (m_pmcSelectedMesh != NULL) && (m_pmcSelectedMesh->bNPatchMode))
  1486.             {
  1487.                 Tesselate(m_pmcSelectedMesh, FALSE);
  1488.             }
  1489.             m_bUpdatedNormalDuringMouseMove = FALSE;
  1490.  
  1491.             m_abArcBall.EndDrag();
  1492.  
  1493.             ReleaseCapture();
  1494.  
  1495.             break;
  1496.  
  1497.         {
  1498.             SDrawElement *pdeCur;
  1499.             bool bChange = false;
  1500.             D3DXMATRIX mat;
  1501.             D3DXVECTOR2 vDelta;
  1502.  
  1503.             
  1504.     
  1505.             UINT bAllFrames = GetAsyncKeyState(VK_SHIFT) & 0x8000;
  1506.             UINT bMoveRootFrame = !(GetAsyncKeyState(VK_CONTROL) & 0x8000);
  1507.             bControl = (GetAsyncKeyState(VK_CONTROL) & 0x8000);
  1508.  
  1509.             vDelta = D3DXVECTOR2(0,10);
  1510.  
  1511.             // normalize based on size of window
  1512.             vDelta.y /= m_sizeClient.cy;
  1513.  
  1514.             // now resize based on size of bounding sphere
  1515.             vDelta *= m_pdeSelected->fRadius * 5;
  1516.  
  1517.             D3DXVECTOR3 vNewDelta;
  1518.             vNewDelta.x = 0;
  1519.             vNewDelta.y = 0;
  1520.             vNewDelta.z = vDelta.y;
  1521.             bChange = true;
  1522.  
  1523.             if (bChange)
  1524.             {
  1525.                 D3DXMatrixTranslation(&mat, vNewDelta.x, vNewDelta.y, vNewDelta.z);
  1526.  
  1527.                 if (bAllFrames)
  1528.                 {
  1529.                     pdeCur = m_pdeHead;
  1530.                     while (pdeCur != NULL)
  1531.                     {
  1532.                         //pdeCur->pframeRoot->m_vTranslation += vNewDelta;
  1533.                         D3DXMatrixMultiply(&pdeCur->pframeRoot->matTrans, &pdeCur->pframeRoot->matTrans, &mat);
  1534.                         pdeCur = pdeCur->pdeNext;
  1535.                     }
  1536.                 }
  1537.                 else if (m_pframeSelected != NULL)
  1538.                 {
  1539.                     if (bMoveRootFrame)
  1540.                     {
  1541.                         D3DXMatrixMultiply(&m_pdeSelected->pframeRoot->matTrans, &m_pdeSelected->pframeRoot->matTrans, &mat);
  1542.                     }
  1543.                     else
  1544.                     {
  1545.                         D3DXMatrixMultiply(&m_pframeSelected->matTrans, &m_pframeSelected->matTrans, &mat);
  1546.                     }
  1547.                     //m_pframeSelected->m_vTranslation += vNewDelta;
  1548.                 }
  1549.                 
  1550.             }
  1551.             break;
  1552.         }
  1553.  
  1554.         case WM_DROPFILES:
  1555.         {
  1556.             HDROP hDropInfo = (HDROP) wparam;
  1557.  
  1558.             char szFilePath[MAX_PATH];
  1559.             UINT nFilesDropped = DragQueryFile( hDropInfo, 0xFFFFFFFF, szFilePath, MAX_PATH );
  1560.             if( nFilesDropped > 0 )
  1561.             {
  1562.                 UINT nBytesCopied = DragQueryFile( hDropInfo, 0, szFilePath, MAX_PATH );
  1563.                 LoadMesh( szFilePath, false );
  1564.             }
  1565.             DragFinish(hDropInfo); 
  1566.             break;
  1567.         }
  1568.  
  1569.         case WM_MOUSEWHEEL:
  1570.         case WM_MOUSEMOVE:
  1571.         {
  1572.             D3DXVECTOR2 vNewPosition;
  1573.             D3DXVECTOR3 vNewDelta;
  1574.             SDrawElement *pdeCur;
  1575.             bool bChange = false;
  1576.             D3DXMATRIX mat;
  1577.  
  1578.             UINT bAllFrames = GetAsyncKeyState(VK_SHIFT) & 0x8000;
  1579.             UINT bMoveRootFrame = !(GetAsyncKeyState(VK_CONTROL) & 0x8000);
  1580.             bControl = (GetAsyncKeyState(VK_CONTROL) & 0x8000);
  1581.  
  1582.             // if shift is down and no buttons are pressed, do a continual select
  1583.             if (bAllFrames && !(wparam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON)))
  1584.             {
  1585.                 SelectionChange(LOWORD(lparam), HIWORD(lparam));
  1586.             }
  1587.  
  1588.             if (m_pdeSelected == NULL)
  1589.                 break;
  1590.  
  1591.             // if in normal modification mode and control and left button are down, then modify the
  1592.             //    selected normal
  1593.             if ( msg == WM_MOUSEMOVE )
  1594.             {
  1595.                 if( m_bVertexSelectionMode && (m_dwVertexSelected != UNUSED32) 
  1596.                     && m_bNormalsMode && bControl && (wparam & MK_LBUTTON))
  1597.                 {
  1598.                     LPD3DXMESH pMeshCur = m_pmcSelectedMesh->bNPatchMode ? m_pmcSelectedMesh->pMeshToTesselate : m_pmcSelectedMesh->pMesh;
  1599.  
  1600.                     D3DVERTEXELEMENT9 pDecl[MAX_FVF_DECL_SIZE];
  1601.  
  1602.                     pMeshCur->GetDeclaration(pDecl);
  1603.                     CD3DXCrackDecl1 cd(pDecl);
  1604.  
  1605.                     PBYTE pvPoints;
  1606.                     D3DXVECTOR3 *pvNormal;
  1607.  
  1608.                     m_abArcBall.Mouse(LOWORD(lparam), HIWORD(lparam));
  1609.                     m_abArcBall.GetMat(&mat);
  1610.  
  1611.                     D3DXMatrixTranspose(&mat, &mat);
  1612.  
  1613.                     pMeshCur->LockVertexBuffer(0, (LPVOID*)&pvPoints);
  1614.  
  1615.                     pvNormal = cd.PvGetNormal(cd.GetArrayElem(pvPoints, m_dwVertexSelected));
  1616.  
  1617.                     D3DXVec3TransformNormal(pvNormal, pvNormal, &mat);
  1618.                     D3DXVec3Normalize(pvNormal, pvNormal);
  1619.  
  1620.                     pMeshCur->UnlockVertexBuffer();
  1621.  
  1622.                     if (m_pmcSelectedMesh->bNPatchMode)
  1623.                     {
  1624.                         Tesselate(m_pmcSelectedMesh, TRUE);
  1625.                     }
  1626.                     else
  1627.                     {
  1628.                         // UNDONE UNDONE - could just update the normal modified
  1629.                         m_pmcSelectedMesh->m_snNormals.Init(m_pmcSelectedMesh->pMesh, UNUSED32, m_pdeSelected->fRadius / 20.0f);
  1630.                     }
  1631.  
  1632.                     m_abArcBall.EndDrag();
  1633.                     m_abArcBall.Reset();
  1634.                     m_abArcBall.BeginDrag(LOWORD(lparam), HIWORD(lparam));
  1635.                     m_bUpdatedNormalDuringMouseMove = TRUE;
  1636.                     break;
  1637.                 }
  1638.  
  1639.                 if (MK_LBUTTON & wparam)
  1640.                 {
  1641.  
  1642.                     m_abArcBall.Mouse(LOWORD(lparam), HIWORD(lparam));
  1643.                             m_abArcBall.GetMat(&mat);
  1644.  
  1645.                     D3DXMatrixTranspose(&mat, &mat);
  1646.  
  1647.                     if (bAllFrames)
  1648.                     {
  1649.                         pdeCur = m_pdeHead;
  1650.                         while (pdeCur != NULL)
  1651.                         {
  1652.                             D3DXMatrixMultiply(&pdeCur->pframeRoot->matRot, &pdeCur->pframeRoot->matRot, &mat);
  1653.                             pdeCur = pdeCur->pdeNext;
  1654.                         }
  1655.                     }
  1656.                     else if (m_pframeSelected != NULL)
  1657.                     {
  1658.                         if (bMoveRootFrame)
  1659.                         {
  1660.                             D3DXMatrixMultiply(&m_pdeSelected->pframeRoot->matRot, &m_pdeSelected->pframeRoot->matRot, &mat);
  1661.                         }
  1662.                         else
  1663.                         {
  1664.                             D3DXMatrixMultiply(&m_pframeSelected->matRot, &m_pframeSelected->matRot, &mat);
  1665.                         }
  1666.                     }
  1667.  
  1668.                     m_abArcBall.EndDrag();
  1669.                     m_abArcBall.Reset();
  1670.                     m_abArcBall.BeginDrag(LOWORD(lparam), HIWORD(lparam));
  1671.                     break;
  1672.                 }
  1673.  
  1674.                 vNewPosition.x = (float)LOWORD(lparam);  // horizontal position of cursor
  1675.                 vNewPosition.y = (float)HIWORD(lparam);  // vertical position of cursor
  1676.  
  1677.                 if (MK_RBUTTON & wparam)
  1678.                 {
  1679.                     D3DXVECTOR2 vDelta;
  1680.  
  1681.                     vDelta = m_vCurMousePosition - vNewPosition;
  1682.  
  1683.                     // normalize based on size of window
  1684.                     vDelta.x /= m_sizeClient.cx;
  1685.                     vDelta.y /= m_sizeClient.cy;
  1686.  
  1687.                     // now resize based on size of bounding sphere
  1688.                     vDelta *= m_pdeSelected->fRadius * 2;
  1689.                     vDelta.x *= -1;
  1690.  
  1691.                     vNewDelta.x = vDelta.x;
  1692.                     vNewDelta.y = vDelta.y;
  1693.                     vNewDelta.z = 0;
  1694.                     bChange = true;
  1695.                 }
  1696.  
  1697.                 if (MK_MBUTTON & wparam)
  1698.                 {
  1699.                     D3DXVECTOR2 vDelta;
  1700.  
  1701.                     vDelta = m_vCurMousePosition - vNewPosition;
  1702.  
  1703.                     // normalize based on size of window
  1704.                     vDelta.y /= m_sizeClient.cy;
  1705.  
  1706.                     // now resize based on size of bounding sphere
  1707.                     vDelta *= m_pdeSelected->fRadius * 5;
  1708.  
  1709.                     vNewDelta.x = 0;
  1710.                     vNewDelta.y = 0;
  1711.                     vNewDelta.z = vDelta.y;
  1712.                     bChange = true;
  1713.                 }
  1714.             }
  1715.             else if( msg == WM_MOUSEWHEEL )
  1716.             {
  1717.                 int nMouseWheelDelta = (short) HIWORD(wparam);
  1718.  
  1719.                 // now resize based on size of bounding sphere
  1720.                 float fDelta = (float)-nMouseWheelDelta/120.0f * m_pdeSelected->fRadius * 0.1f;
  1721.  
  1722.                 vNewDelta.x = 0;
  1723.                 vNewDelta.y = 0;
  1724.                 vNewDelta.z = fDelta;
  1725.                 bChange = true;
  1726.             }
  1727.  
  1728.             if (bChange)
  1729.             {
  1730.                 D3DXMatrixTranslation(&mat, vNewDelta.x, vNewDelta.y, vNewDelta.z);
  1731.  
  1732.                 if (bAllFrames)
  1733.                 {
  1734.                     pdeCur = m_pdeHead;
  1735.                     while (pdeCur != NULL)
  1736.                     {
  1737.                         //pdeCur->pframeRoot->m_vTranslation += vNewDelta;
  1738.                         D3DXMatrixMultiply(&pdeCur->pframeRoot->matTrans, &pdeCur->pframeRoot->matTrans, &mat);
  1739.                         pdeCur = pdeCur->pdeNext;
  1740.                     }
  1741.                 }
  1742.                 else if (m_pframeSelected != NULL)
  1743.                 {
  1744.                     if (bMoveRootFrame)
  1745.                     {
  1746.                         D3DXMatrixMultiply(&m_pdeSelected->pframeRoot->matTrans, &m_pdeSelected->pframeRoot->matTrans, &mat);
  1747.                     }
  1748.                     else
  1749.                     {
  1750.                         D3DXMatrixMultiply(&m_pframeSelected->matTrans, &m_pframeSelected->matTrans, &mat);
  1751.                     }
  1752.                     //m_pframeSelected->m_vTranslation += vNewDelta;
  1753.                 }
  1754.             }
  1755.  
  1756.             if( msg == WM_MOUSEMOVE ) 
  1757.             {
  1758.                 //update the current mouse position
  1759.                 m_vCurMousePosition = vNewPosition;
  1760.             }
  1761.             break;
  1762.         }
  1763.     }
  1764.  
  1765.     return CD3DXApplication::OnMessage(hwnd, msg, wparam, lparam);
  1766. }
  1767.